package io.mft.runtime.function.combination.component;

import java.util.concurrent.Future;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.mft.api.domain.ExecuteMode;
import io.mft.commons.function.ExecuteReturn;
import io.mft.flow.core.executable.ExecutableType;
import io.mft.flow.core.executable.component.NodeComponent;
import io.mft.flow.data.ChainContext;
import io.mft.runtime.MFTApiExecutor;
import io.mft.runtime.function.ApiContext;
import io.mft.runtime.function.ApiExecutorObject;
import io.mft.runtime.function.ApiFunctionRequest;
import io.mft.runtime.function.ApiFunctionResponse;
import io.mft.runtime.function.process.ApiFunctionProcessExecutor;
import io.mft.runtime.thread.AsyncExecuteThreadPool;
import io.mft.runtime.thread.AsyncExecuteThreadPool.AsyncWorker;

/**
 * 原子接口逻辑处理单元编排组件
 * 
 * @说明：TODO
 * @类型名称：CombinationApiFunctionProcessComponent
 * @创建者: 胡常建
 * @创建时间: 2021年2月28日 下午4:55:02
 * @修改者: 胡常建
 * @修改时间: 2021年2月28日 下午4:55:02
 */
public class CombinationApiFunctionProcessComponent extends NodeComponent {

	Logger logger=LoggerFactory.getLogger(getClass());

	@Override
	public ExecutableType getType() {
		return ExecutableType.NODE;
	}

	@Override
	public String getId() {
		return CombinationApiFunctionProcessComponent.class.getName();
	}

	@Override
	public ExecuteReturn execute(ChainContext context) throws Exception {
		String uniqueId=context.getExecutableUniqueId();
		logger.debug("原子接口逻辑处理单元编排组件->>>逻辑单元编排Chain:{}->>>当前规则KEY:{}->>>初始入参:{}->>>过程入参:{}",context.getChainName(),uniqueId,context.getChainInitialRequest(),context.getRequest());
		ApiExecutorObject apiExecutorObject=MFTApiExecutor.getInstance().getRuntimeResource().getApiCache().getApiExecutorObject(context.getChainName());
		ApiFunctionProcessExecutor<?> regulationExecutor = apiExecutorObject.getRegulationExecutor(uniqueId);
		ExecuteMode executeMode=regulationExecutor.getRegulation().getExecuteMode();
		ApiFunctionRequest apiFunctionRequest=new ApiFunctionRequest(context.getRequest().getRequestValue());
		ApiFunctionResponse apiFunctionResponse=new ApiFunctionResponse(context.getResponse());
		ApiContext regulationExecutorContext = new ApiContext(apiExecutorObject, apiFunctionRequest,apiFunctionResponse);
		if (executeMode==ExecuteMode.async||executeMode==ExecuteMode.syncWaitAsync) {
			Future<?> future=AsyncExecuteThreadPool.execute(regulationExecutor.getRegulation(), new AsyncWorker() {
				@Override
				public void work() {
					try {
						regulationExecutor.doExecute(regulationExecutorContext);
					} catch (Exception e) {
						logger.error("",e);
					}
				}
			});
			return ExecuteReturn.builder().asyncFuture(future).build();
		}else {
			return regulationExecutor.doExecute(regulationExecutorContext);
		}
	}

}
